﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.ESB.Resolver;
using Microsoft.Practices.ESB.Resolver.BRE;
using Microsoft.Practices.ESB.Exception.Management;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.XLANGs.BaseTypes;
using System.Reflection;

namespace BizTalk.ESB.Extensions.Resolvers
{
    public class ContextResolution
    {
        public List<ContextProperty> Properties { get; set; }

        public String GetContextPropertyValue(String propertyName, String propertyNamespace)
        {
            if (this.Properties != null)
            {
                if (this.Properties.Exists(
                    prop => (prop.PropertyName == propertyName && prop.PropertyNamespace == propertyNamespace)))
                {
                    ContextProperty p = this.Properties.Find(prop => (prop.PropertyNamespace == propertyNamespace && prop.PropertyName == propertyName));
                    return p.PropertyValue;
                }
                else
                {
                    return String.Empty;
                }
            }
            else
            {
                return null;
            }
        }

    }

    //public class ContextResolutionManager
    //{
    //    public static BRE CreateResolverDescriptor(String config, String resolver, out Boolean UseMsgContext)
    //    {
    //        BRE breWrapper;
    //        UseMsgContext = false;

    //        if (config == null)
    //        {
    //            throw new ArgumentNullException("config");
    //        }
    //        if (resolver == null)
    //        {
    //            throw new ArgumentNullException("resolver");
    //        }

    //        Dictionary<String, String> facts = null;
    //        try
    //        {
    //            BRE breTemp = new BRE();
    //            breTemp.useMsg = false;
    //            facts = ResolverMgr.GetFacts(config, resolver);
    //            breTemp.policy = ResolverMgr.GetConfigValue(facts, true, "policy");
    //            breTemp.version = ResolverMgr.GetConfigValue(facts, false, "version");
    //            Boolean.TryParse(ResolverMgr.GetConfigValue(facts, false, "useMsgContext"), out UseMsgContext); ;
    //            Boolean useMessage, recognizeMessage;
    //            breTemp.useMsgSpecified = Boolean.TryParse(
    //                ResolverMgr.GetConfigValue(facts, false, "useMsg")
    //                , out useMessage);
    //            breTemp.recognizeMessageFormatSpecified = Boolean.TryParse(
    //                ResolverMgr.GetConfigValue(facts, false, "recognizeMessageFormat")
    //                , out recognizeMessage);
    //            breTemp.useMsg = useMessage;
    //            breTemp.recognizeMessageFormat = recognizeMessage;

    //            breWrapper = breTemp;
    //        }
    //        catch (Exception e)
    //        {
    //            EventLogger.Write(MethodBase.GetCurrentMethod(), e);
    //            throw;
    //        }
    //        finally
    //        {
    //            if (facts != null)
    //            {
    //                facts.Clear();
    //                facts = null;
    //            }
    //        }

    //        return breWrapper;
    //    }

    //    public static void SetResolverDictionary(ContextResolution resolution, Dictionary<String, String> dictionary)
    //    {
    //        try
    //        {
    //            dictionary.Add("Resolver.PropertyNamespace", resolution.PropertyNamespace.ToString());
    //            dictionary.Add("Resolver.PropertyName", resolution.PropertyName);
    //            dictionary.Add("Resolver.DefaultValue", resolution.DefaultValue);
    //            dictionary.Add("Resolver.MessageType", resolution.MessageType);
    //            dictionary.Add("Resolver.DocumentSpecStrongName", resolution.DocumentSpecStrongName);
    //        }
    //        catch { }
    //    }

    //    public static void SetContext(ContextResolution resolution, IBaseMessage message)
    //    {
    //        if (message == null)
    //        {
    //            throw new ArgumentNullException("message");
    //        }
    //        if (resolution == null)
    //        {
    //            throw new ArgumentNullException("resolution");
    //        }
    //        try
    //        {
    //            resolution.MessageType = ((String)ContextResolutionManager.GetMsgProperty(message
    //                , "MessageType", @"http://schemas.microsoft.com/BizTalk/2003/system-properties")) ?? String.Empty;
    //            resolution.DocumentSpecStrongName = ((String)ContextResolutionManager.GetMsgProperty(message
    //                , "SchemaStrongName", @"http://schemas.microsoft.com/BizTalk/2003/system-properties")) ?? String.Empty;
    //            if (String.IsNullOrEmpty(resolution.DocumentSpecStrongName) == false)
    //            {
    //                Int32 index = resolution.DocumentSpecStrongName.IndexOf(",", StringComparison.CurrentCultureIgnoreCase);
    //                if ((index > 0) && (index < resolution.DocumentSpecStrongName.Length))
    //                {
    //                    resolution.DocumentSpecStrongName = resolution.DocumentSpecStrongName.Substring(0, index);
    //                }
    //            }
    //        }
    //        catch (Exception e)
    //        {
    //            EventLogger.Write(MethodBase.GetCurrentMethod(), e);
    //            throw;
    //        }
    //    }
        
    //    public static void SetContext(ContextResolution resolution, XLANGMessage message)
    //    {
    //        if (message == null)
    //        {
    //            throw new ArgumentNullException("message");
    //        }
    //        if (resolution == null)
    //        {
    //            throw new ArgumentNullException("resolution");
    //        }
    //        try
    //        {
    //            resolution.MessageType = ((String)ContextResolutionManager.GetMsgProperty(message
    //                , typeof(BTS.MessageType))) ?? String.Empty;
    //            resolution.DocumentSpecStrongName = ((String)ContextResolutionManager.GetMsgProperty(message
    //                , typeof(BTS.SchemaStrongName))) ?? String.Empty;
    //            if (String.IsNullOrEmpty(resolution.DocumentSpecStrongName) == false)
    //            {
    //                Int32 index = resolution.DocumentSpecStrongName.IndexOf(",", StringComparison.CurrentCultureIgnoreCase);
    //                if ((index > 0) && (index < resolution.DocumentSpecStrongName.Length))
    //                {
    //                    resolution.DocumentSpecStrongName = resolution.DocumentSpecStrongName.Substring(0, index);
    //                }
    //            }
    //        }
    //        catch (Exception e)
    //        {
    //            EventLogger.Write(MethodBase.GetCurrentMethod(), e);
    //            throw;
    //        }
    //    }

    //    public static Object GetMsgProperty(XLANGMessage message, Type property)
    //    {
    //        Object prop;
    //        if (message == null)
    //        {
    //            throw new ArgumentNullException("message");
    //        }
    //        if (property == null)
    //        {
    //            throw new ArgumentNullException("property");
    //        }
    //        Object PropertyValue = null;
    //        try
    //        {
    //            PropertyValue = message.GetPropertyValue(property);
    //            prop = PropertyValue;
    //        }
    //        catch (Exception e)
    //        {
    //            EventLogger.Write(MethodBase.GetCurrentMethod(), e);
    //            throw;
    //        }
    //        finally
    //        {
    //            if (PropertyValue != null)
    //            {
    //                PropertyValue = null;
    //            }
    //        }
    //        return prop;
    //    }

    //    public static Object GetMsgProperty(IBaseMessage message, String PropertyName, String PropertyNamespace)
    //    {
    //        if (String.IsNullOrEmpty(PropertyName))
    //        {
    //            throw new ArgumentException("PropertyName");
    //        }
    //        if (String.IsNullOrEmpty(PropertyNamespace))
    //        {
    //            throw new ArgumentException("PropertyNamespace");
    //        }
    //        if (message == null)
    //        {
    //            throw new ArgumentException("message");
    //        }
    //        return message.Context.Read(PropertyName, PropertyNamespace);
    //    }
    //}

    public class ContextProperty
    {
        public String PropertyNamespace { get; set; }
        public String PropertyName { get; set; }
        public String PropertyValue { get; set; }
    }

    public class DynamicContextResolution
    {
        public Dictionary<String, String> ContextProperties { get; set; }

        public String GetContextPropertyValue(String Name, String Namespace)
        {
            String key = Namespace + "_" + Name;
            if (this.ContextProperties.ContainsKey(key))
            {
                return this.ContextProperties[key];
            }
            else
            {
                return String.Empty;
            }
        }
    }
}
